using System;
using System.IO;
using System.Text;
using System.Web;

namespace Isis.Handlers
{
    /// <summary>
    /// Reads a resource from the assembly manifest and returns its contents
    /// as the response entity.
    /// </summary>
    internal sealed class ManifestResourceHandler : IHttpHandler
    {
        private readonly string _contentType;
        private readonly Encoding _responseEncoding;
        private string _resourceName;

        #region Constructors

        public ManifestResourceHandler(string resourceName, string contentType) :
            this(resourceName, contentType, null)
        {
        }

        public ManifestResourceHandler(string resourceName, string contentType, Encoding responseEncoding)
        {
            _resourceName = resourceName;
            _contentType = contentType;
            _responseEncoding = responseEncoding;
        }

        #endregion

        public bool IsReusable
        {
            get { return false; }
        }

        public void ProcessRequest(HttpContext context)
        {
            //
            // Grab the resource stream from the manifest.
            //

            Type thisType = GetType();
            foreach (string strResource in thisType.Assembly.GetManifestResourceNames())
            {
                //context.Response.Write(strResource + "<br />");
                if (strResource.EndsWith(_resourceName))
                {
                    _resourceName = strResource;
                }
            }

            using (Stream stream = thisType.Assembly.GetManifestResourceStream(_resourceName))
            {
                if (stream == null)
                {
                    context.Response.Write("Resource not found: " + _resourceName);
                    return;
                }
                //
                // Allocate a buffer for reading the stream. The maximum size
                // of this buffer is fixed to 4 KB.
                //

                var buffer = new byte[Math.Min(stream.Length, 4096)];

                //
                // Set the response headers for indicating the content type 
                // and encoding (if specified).
                //

                HttpResponse response = context.Response;
                response.ContentType = _contentType;

                if (_responseEncoding != null)
                {
                    response.ContentEncoding = _responseEncoding;
                }

                //
                // Finally, write out the bytes!
                //

                int bytesWritten = 0;

                do
                {
                    int readCount = stream.Read(buffer, 0, buffer.Length);
                    response.OutputStream.Write(buffer, 0, readCount);
                    bytesWritten += readCount;
                } while (bytesWritten < stream.Length);
            }
        }
    }
}